package com.base.cn.platform.os.service.planTools;

import com.base.cn.platform.os.common.mybatis.BaseBiz;
import com.base.cn.platform.os.common.mybatis.Pagination;
import com.base.cn.platform.os.common.utils.DataUtil;
import com.base.cn.platform.os.common.utils.ObjectUtils;
import com.base.cn.platform.os.common.utils.StringUtils;
import com.base.cn.platform.os.common.utils.result.ResultUtil;
import com.base.cn.platform.os.dao.planTools.PopupSloganDao;
import com.base.cn.platform.os.entity.planTools.PopupSlogan;
import com.base.cn.platform.os.entity.planTools.PopupSloganCondition;
import com.base.cn.platform.os.entity.planTools.PopupSloganDetail;
import com.base.cn.platform.os.service.manage.planTools.PopupSloganDetailService;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * 弹窗广告Biz
 *
 * @Author: lxr
 * @Date: 2020/06/28 18:49
 */
@Service
public class PopupSloganBiz extends BaseBiz<PopupSlogan, PopupSloganDao> {

    @Autowired
    private PopupSloganDetailService popupSloganDetailService;

    public PageInfo<PopupSlogan> findPopupSloganListPage(PopupSloganCondition condition, Pagination page) {
        PageInfo<PopupSlogan> pageInfo = this.findPage(getWhereSql(condition), page, null);
        pageInfo.getList().stream().forEach(p -> {
            p.setThisStatus(p.getThisState());
        });
        this.setData(pageInfo.getList());
        return pageInfo;
    }


    public PopupSlogan savePopupSlogan(PopupSlogan popupSlogan) {
        if (DataUtil.idIsNotNull(popupSlogan.getId())) {
            this.updateById(popupSlogan, null);
        } else {//添加
            popupSlogan.setStatus(1);
            this.save(popupSlogan);
        }
        return popupSlogan;
    }

    public void updatePopupSloganStatus(String id, int status) {
        PopupSlogan popupSlogan = new PopupSlogan();
        if (status == 2) {
            popupSlogan.setStatus(status);
        } else if (status == 3) {
            popupSlogan.setStartTime(new Date());
        } else if (status == 4) {
            popupSlogan.setEndTime(new Date());
        }
        this.updateByWhereSql(popupSlogan, " id in (" + id + ")");
    }

    public PopupSlogan findPopupSloganById(BigDecimal id) {
        List<PopupSlogan> popupSloganList = this.findPopupSloganById(id.toString());
        if (ObjectUtils.isNotEmpty(popupSloganList)) {
            return popupSloganList.get(0);
        }
        return null;
    }

    public List<PopupSlogan> findPopupSloganById(String ids) {
        PopupSloganCondition condition = new PopupSloganCondition();
        condition.setQueryIds(ids);
        List<PopupSlogan> popupSloganList = this.find(getWhereSql(condition), null, null);
        return popupSloganList;
    }

    public Map getIndexPopupSlogan(String type, String userId) {
        StringBuilder whereSql = new StringBuilder(" status=1 and now() > startTime and endTime > now()");
        if ("web".equals(type)) {
            whereSql.append("and putDitchPc = 1");
        } else {
            whereSql.append("and putDitchMobile = 1");
        }
        PopupSlogan popupSlogan = this.findOne(whereSql.toString(), null);
        if (ObjectUtils.isNotEmpty(popupSlogan)) {
            boolean flag = false;
            List<PopupSloganDetail> popupSloganDetailList = popupSloganDetailService.finBySql( "popupSloganId = " + popupSlogan.getId() + " and userId = '" + userId + "' order by createTime desc");
            if (popupSlogan.getAppearType().intValue() == 1) { //首次访问页面时出现，之后不再出现
                if (ObjectUtils.isNotEmpty(popupSloganDetailList)) {
                    return ResultUtil.ERROR("");
                } else {
                    flag = true;
                }
            } else { //间隔几天
                if (ObjectUtils.isEmpty(popupSloganDetailList)) {
                    flag = true;
                } else if (equation(popupSloganDetailList.get(0).getCreateTime().getTime(), System.currentTimeMillis()) >= Integer.valueOf(popupSlogan.getAppearData())) {
                    flag = true;
                } else {
                    return ResultUtil.ERROR("");
                }
            }
            if (flag) {
                Map map = new HashMap();
                map.put("userId", userId);
                map.put("popupSloganId", popupSlogan.getId());
                map.put("show", 1);
                map.put("click", 0);
                BigDecimal popupSloganDetailId = popupSloganDetailService.savePopupSloganDetail( map);
                popupSlogan.setPopupSloganDetailId(popupSloganDetailId);
                return ResultUtil.SUCCESS(popupSlogan);
            } else {
                return ResultUtil.ERROR("");
            }
        } else {
            return ResultUtil.ERROR("");
        }
    }

    private void setData(List<PopupSlogan> popupSloganList){
        if(ObjectUtils.isEmpty(popupSloganList)){
            return;
        }
        String popupSloganIds = popupSloganList.stream().map(e -> String.valueOf(e.getId())).collect(Collectors.joining(","));
        List<PopupSloganDetail> popupSloganDetailList = popupSloganDetailService.finBySql("popupSloganId in ("+popupSloganIds+")");
        Map<BigDecimal, List<PopupSloganDetail>> popupSloganDetailListMap = popupSloganDetailList.stream().collect(Collectors.groupingBy(PopupSloganDetail::getPopupSloganId));
        // 创建一个数值格式化对象
        NumberFormat numberFormat = NumberFormat.getInstance();
        // 设置精确到小数点后2位
        numberFormat.setMaximumFractionDigits(2);
        popupSloganList.stream().forEach(p->{
            if(popupSloganDetailListMap.containsKey(p.getId())){
                List<PopupSloganDetail> popupSloganDetails = popupSloganDetailListMap.get(p.getId());
                Integer clickNum = popupSloganDetails.stream()
                        .mapToInt(s -> s.getClick())
                        .sum();
                Integer showNum = popupSloganDetails.stream()
                        .mapToInt(s -> s.getShow())
                        .sum();
                String clickRate = numberFormat.format((float) clickNum / (float) showNum * 100);
                p.setClickNum(clickNum);
                p.setShowNum(showNum);
                p.setClickRate(clickRate+"%");
            }else{
                p.setClickNum(0);
                p.setShowNum(0);
                p.setClickRate("0.00%");
            }
        });
    }

    private String getWhereSql(PopupSloganCondition condition) {
        StringBuilder whereSql = new StringBuilder(" status=1");
        if (ObjectUtils.isNotEmpty(condition)) {
            if (StringUtils.isNotEmpty(condition.getName())) {
                whereSql.append(" and name like '%").append(condition.getName()).append("%'");
            }
            if (StringUtils.isNotEmpty(condition.getQueryIds())) {
                whereSql.append(" and id in (").append(condition.getQueryIds()).append(")");
            }
            if (StringUtils.isNotEmpty(condition.getPutDitchType())) {
                if ("1".equals(condition.getPutDitchType())) {
                    whereSql.append(" and putDitchPc = 1");
                } else if ("2".equals(condition.getPutDitchType())) {
                    whereSql.append(" and putDitchMobile = 1");
                }
            }
            if (StringUtils.isNotEmpty(condition.getStatusType())) {
                if ("1".equals(condition.getStatusType())) {
                    whereSql.append(" and now() > startTime and endTime > now()");
                } else if ("2".equals(condition.getStatusType())) {
                    whereSql.append(" and startTime > now()");
                } else {
                    whereSql.append(" and endTime < now()");
                }
            }
        }
        whereSql.append(" order by createTime desc");
        return whereSql.toString();
    }

    public static int equation(long startTime, long endTime) {
        int newL = (int) ((endTime - startTime) / (1000 * 3600 * 24));
        return newL;
    }
}
